package tech.aistar.design.singleton.version04;

import java.io.Serializable;

/**
 * 本类用来演示: 懒汉模式 - 多线程安全 - 双重检测锁
 * 笔试题中
 *
 * @author: success
 * @date: 2021/3/17 11:17 上午
 */
public class Single04Demo {
    private static volatile Single04Demo instance = null;

    private Single04Demo(){
        System.out.println("Single04Demo...");
    }

    public static Single04Demo getInstance(){
        //1. 第一重判断
        //①A和B线程仍然会同时进行判断...
        //⑥跑得慢的线程,慢吞吞执行到此处,进行非空判断
        //  此处instance已经被A线程初始化完毕了
        //  不会进入,不会竞争和申请"锁"这昂贵资源
        if(null == instance){
            //②A和B线程同时抢锁资源 - 锁资源只能被一个线程抢占,比如被A线程抢到了.
            //④A和B进行抢 , 假设B线程抢到,B线程进入...
            synchronized (Single04Demo.class){//同步代码块 - 当前只能由获取到锁资源的线程进去执行.
                //2. 第二重判断
                //⑤B线程执行到此处进行非空判断,false
                if(null == instance){
                    //③A线程进行了初始化,释放锁资源.
                    instance = new Single04Demo();
                }
            }
        }
        return instance;
    }
}
class TestSingle04Demo{
    public static void main(String[] args) {
        Single04Demo s1 = Single04Demo.getInstance();
        Single04Demo s2 = Single04Demo.getInstance();
        System.out.println(s1 == s2);
    }
}
